package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import design.onekey.base.BaseEntity;
import design.onekey.base.Constants;
import design.onekey.mapper.SysFunctionMapper;
import design.onekey.model.SysFunction;
import design.onekey.service.ISysFunctionService;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* @Description: SysFunction服务实现
* @author
* @date 2020-06-05 04:03:04
* @version V1.0
 */
@Service
public class SysFunctionServiceImpl extends ServiceImpl<SysFunctionMapper, SysFunction> implements ISysFunctionService {

	@Autowired
    @Qualifier("shiroFilter")
	@Lazy
    private ShiroFilterFactoryBean shiroFilterFactoryBean;

	/**
	 * @Fields applicationName : 应用名称注入
	 * @author blcloak
	 * @date 2020-07-13 07:18:25
	 */
	@Value("${spring.application.name}")
	private String applicationName;



	/**
	 * @Title: getFunctionsByType
	 * @Description: 根据类型获取功能
	 * @param type
	 * @return
	 * @author blcloak
	 * @date 2020-07-13 08:56:55
	 */
	@Override
	public List<SysFunction> getFunctionsByType(int type) {
		QueryWrapper<SysFunction> queryWrapper = new QueryWrapper<SysFunction>();
		queryWrapper.eq("function_type", type);
		queryWrapper.eq("del_flag", 1);
		return this.list(queryWrapper);
	}

	 /**
	  * @Title: getFunctionsByRole
	  * @Description: 根据角色获取功能
	  * @param roleId
	  * @return
	  * @author blcloak
	  * @date 2020-06-05 05:52:02
	  */
	 @Override
	 public List<SysFunction> getFunctionsByRole(Long roleId) {
		 return this.baseMapper.getFunctionsByRole(roleId);
	 }

	 @Override
	 public List<SysFunction> getAllFunctions() {
		 QueryWrapper<SysFunction> queryWrapper = new QueryWrapper<SysFunction>();
		 queryWrapper.eq("del_flag", 1);
		 return this.list(queryWrapper);
	 }


	/**
	 * @Title: updatePermission
	 * @Description: 动态更新权限，不需要重启服务
	 * @return
	 * @author blcloak
	 * @date 2020-06-12 03:26:48
	 */
	 @Override
	 public BaseEntity updatePermission() {
		 BaseEntity result = new BaseEntity();
		 synchronized (shiroFilterFactoryBean) {
			 AbstractShiroFilter shiroFilter;
			 try {
				 shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
			 } catch (Exception e) {
				 throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
			 }
			 PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver)shiroFilter.getFilterChainResolver();
			 DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
			 // 清空老的权限控制
			 manager.getFilterChains().clear();
			 shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
			 Map<String, String> section = new LinkedHashMap<String, String>();
			 List<SysFunction> list = this.getFunctionsByType(1);
			 if (list != null && list.size() > 0) {
				 for (SysFunction sysFunction : list) {
					 if (1==sysFunction.getRule()) {
						 //公开访问，不需要鉴权
						 section.put(sysFunction.getFunctionUrl(), Constants.PUBLIC_STRING);
					 }else if (2 == sysFunction.getRule()) {
						 //只需校验登录token
						 section.put(sysFunction.getFunctionUrl(), Constants.JWT_STRING);
					 }else {
						 //需校验登录token和访问权限
						 section.put(sysFunction.getFunctionUrl(),
								 MessageFormat.format(Constants.PC_ADMIN_PREMISSION_STRING, sysFunction.getFunctionCode()));
					 }
				 }
			 }
			 shiroFilterFactoryBean.setFilterChainDefinitionMap(section);
			 // 重新构建生成
			 Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
			 for (Map.Entry<String, String> entry : chains.entrySet()) {
				 String url = entry.getKey();
				 String chainDefinition = entry.getValue().trim().replace(" ", "");
				 manager.createChain(url, chainDefinition);
			 }
		 }
		 return result;
	 }

}
